﻿/******************************************************************************
	Cobalt - utility libraries for building XNA games
	Copyright (C) 2008 Philip Djonov

	This program is free software; you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2 of the License, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
	for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the
	
		Free Software Foundation, Inc.
		51 Franklin Street, Fifth Floor
		Boston, MA  02110-1301, USA.
******************************************************************************/

using System;
using System.Collections.Generic;

namespace Cobalt.Framework
{

	public static class Boxes
	{

		public sealed class Box<T>
			where T : struct
		{
			private Dictionary<T, object> values = new Dictionary<T, object>();

			internal Box()
			{
			}

			public object this[T val]
			{
				get
				{
					object ret;
					if( !values.TryGetValue( val, out ret ) )
					{
						ret = (object)val;
						values.Add( val, ret );
					}

					return ret;
				}
			}
		}

		public sealed class IntBox
		{
			private const int MinCommonInt = -64;
			private const int MaxCommonInt = MinCommonInt + 1024;

			private object[] commonInts = new object[MaxCommonInt - MinCommonInt];
			private Dictionary<int, object> uncommonInts = new Dictionary<int, object>();

			internal IntBox()
			{
				for( int i = 0; i < commonInts.Length; i++ )
					commonInts[i] = (object)(MinCommonInt + i);
			}

			public object this[int val]
			{
				get
				{
					if( val >= MinCommonInt && val < MaxCommonInt )
						return commonInts[val - MinCommonInt];

					object ret;
					if( !uncommonInts.TryGetValue( val, out ret ) )
					{
						ret = (object)val;
						uncommonInts.Add( val, ret );
					}

					return ret;
				}
			}

		}

		public static readonly IntBox Int32s = new IntBox();

		public static T UnboxOrDfault<T>( object obj, T defaultValue )
			where T : struct
		{
			if( obj is T )
				return (T)obj;

			return defaultValue;
		}

		public static T UnboxOrDfault<T>( object obj )
			where T : struct
		{
			if( obj is T )
				return (T)obj;

			return default( T );
		}

	}

}